package com.tianji.learning.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.api.cache.CategoryCache;
import com.tianji.api.client.course.CatalogueClient;
import com.tianji.api.client.course.CourseClient;
import com.tianji.api.client.search.SearchClient;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.course.CataSimpleInfoDTO;
import com.tianji.api.dto.course.CourseFullInfoDTO;
import com.tianji.api.dto.course.CourseSimpleInfoDTO;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.exceptions.DbException;
import com.tianji.common.utils.*;
import com.tianji.learning.domain.dto.QuestionFormDTO;
import com.tianji.learning.domain.po.InteractionQuestion;
import com.tianji.learning.domain.po.InteractionReply;
import com.tianji.learning.domain.query.QuestionAdminPageQuery;
import com.tianji.learning.domain.query.QuestionPageQuery;
import com.tianji.learning.domain.vo.QuestionAdminVO;
import com.tianji.learning.domain.vo.QuestionVO;
import com.tianji.learning.mapper.InteractionQuestionMapper;
import com.tianji.learning.service.IInteractionQuestionService;
import com.tianji.learning.service.IInteractionReplyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 互动提问的问题表 服务实现类
 * </p>
 *
 * @author lyh
 * @since 2024-12-11
 */
@Service
public class InteractionQuestionServiceImpl extends ServiceImpl<InteractionQuestionMapper, InteractionQuestion> implements IInteractionQuestionService {

    @Autowired
    private UserClient userClient;
    @Autowired
    private IInteractionReplyService replyService;

    @Autowired
    private SearchClient searchClient;
    @Autowired
    private CategoryCache categoryCache;
    @Autowired
    private CourseClient courseClient;
    @Autowired
    private CatalogueClient catalogueClient;

    /**
     * 新增问题
     * @param dto
     */
    @Override
    public void saveQuestion(QuestionFormDTO dto) {
        InteractionQuestion question = BeanUtils.copyBean(dto, InteractionQuestion.class);
        question.setUserId(UserContext.getUser());
        save(question);
    }

    /**
     * 分页查询问答列表
     * @param query
     * @return
     */
    @Override
    public PageDTO<QuestionVO> queryQuestionPage(QuestionPageQuery query) {
        if(query.getCourseId()==null&&query.getSectionId()==null){
            throw new BadRequestException("参数有异常");
        }
        Long userId = UserContext.getUser();
        //分页查询
        Page<InteractionQuestion> page = lambdaQuery()
                .select(InteractionQuestion.class, q -> !"description".equals(q.getProperty()))//查询除了description之外的属性
                .eq(query.getCourseId() != null, InteractionQuestion::getCourseId, query.getCourseId())
                .eq(query.getSectionId() != null, InteractionQuestion::getSectionId, query.getSectionId())
                .eq(InteractionQuestion::getHidden, false)
                .eq(BooleanUtils.isTrue(query.getOnlyMine()), InteractionQuestion::getUserId, userId)
                .page(query.toMpPageDefaultSortByCreateTimeDesc());
        List<InteractionQuestion> records = page.getRecords();
        //判断分页结果是否为空
        if(CollUtils.isEmpty(records)){
            //返回控的分页结果
            return PageDTO.empty(page);
        }
        //得到分页结果所有的userId
        Set<Long> set = records.stream().map(InteractionQuestion::getUserId).collect(Collectors.toSet());

        List<QuestionVO> list = new ArrayList<>();

        //得到全部的最新回答id
        Set<Long> answerIds = records.stream().map(r -> r.getLatestAnswerId())
                .filter(id -> id != null)
                .collect(Collectors.toSet());
        //查询所有最新回答列表
        Map<Long, InteractionReply> replyMap=new HashMap<>();
        if(CollUtils.isNotEmpty(answerIds)) {
            List<InteractionReply> replies = replyService.listByIds(answerIds);
            replyMap = replies.stream().collect(Collectors.toMap(InteractionReply::getId, r -> r));
            Set<Long> collect = replies.stream().map(InteractionReply::getUserId).collect(Collectors.toSet());
            set.addAll(collect);
        }
        //调用userClient的queryUserByIds得到用户的信息
        List<UserDTO> userDTOS = userClient.queryUserByIds(set);
        //讲结果转为map，方便查询
        Map<Long, UserDTO> map = userDTOS.stream().collect(Collectors.toMap(UserDTO::getId, user -> user));
        //遍历分页结果，填充属性
        for (InteractionQuestion record : records) {
            QuestionVO vo = BeanUtils.copyBean(record, QuestionVO.class);
            UserDTO userDTO = map.getOrDefault(record.getUserId(),new UserDTO());
            //如果没有匿名，则设置用户名和头像
            if(!record.getAnonymity()&&userDTO!=null) {
                vo.setUserName(userDTO.getName());
                vo.setUserIcon(userDTO.getIcon());
            }
            InteractionReply reply = replyMap.getOrDefault(record.getLatestAnswerId(), new InteractionReply());
            vo.setLatestReplyContent(reply.getContent());
            if(reply.getAnonymity()!=null&&!reply.getAnonymity()) {
                UserDTO userDTO1 = map.getOrDefault(reply.getUserId(),new UserDTO());
                vo.setLatestReplyUser(userDTO1.getName());
            }
            list.add(vo);
        }
        return PageDTO.of(page,list);
    }

    @Override
    public QuestionVO getQuestionById(Long id) {
        InteractionQuestion question = this.getById(id);
        if(question==null){
            return null;
        }
        QuestionVO vo = BeanUtils.copyBean(question, QuestionVO.class);
        UserDTO userDTO = userClient.queryUserById(question.getUserId());
        if(userDTO!=null&&!question.getAnonymity()) {
            vo.setUserName(userDTO.getName());
            vo.setUserIcon(userDTO.getIcon());
        }
        return vo;
    }

    /**
     * 管理端分页查询互动问题
     * @param query
     * @return
     */
    @Override
    public PageDTO<QuestionAdminVO> queryQuestionPageAdmin(QuestionAdminPageQuery query) {
        List<Long> courseIds=new ArrayList<>();
        if(StringUtils.isNotEmpty(query.getCourseName())){
            courseIds = searchClient.queryCoursesIdByName(query.getCourseName());
         //判断es中获取的 courseIds是否为空，为空说明，查询条件中的课程名称都不符合，返回空page集合
            if(CollUtils.isEmpty(courseIds)){
                return PageDTO.empty(0L,0L);
            }
        }
        //分页查询条件
        Page<InteractionQuestion> page = this.lambdaQuery()
                .in(CollUtils.isNotEmpty(courseIds), InteractionQuestion::getCourseId, courseIds)
                .eq(query.getStatus() != null, InteractionQuestion::getStatus, query.getStatus())
                .ge(query.getBeginTime() != null, InteractionQuestion::getUpdateTime, query.getBeginTime())
                .le(query.getEndTime() != null, InteractionQuestion::getUpdateTime, query.getEndTime())
                .page(query.toMpPageDefaultSortByCreateTimeDesc());
        List<InteractionQuestion> records = page.getRecords();
        if(CollUtils.isEmpty(records)){
            return PageDTO.empty(page);
        }
        Set<Long> userIds=new HashSet<>();//存在用户id
        Set<Long> courses=new HashSet<>();//存放课程id
        Set<Long> catalogueIds=new HashSet<>();//存放章、节id

        for (InteractionQuestion record : records) {
            userIds.add(record.getUserId());
            courses.add(record.getCourseId());
            catalogueIds.add(record.getChapterId());
            catalogueIds.add(record.getSectionId());
        }
        //查询用户姓名列表
        List<UserDTO> userDTOS = userClient.queryUserByIds(userIds);
        Map<Long, String> users = userDTOS.stream().collect(Collectors.toMap(UserDTO::getId, UserDTO::getName));
        //存放课程信息
        List<CourseSimpleInfoDTO> infoDTOS = courseClient.getSimpleInfoList(courses);
        Map<Long, CourseSimpleInfoDTO> courseList = infoDTOS.stream().collect(Collectors.toMap(CourseSimpleInfoDTO::getId, c -> c));
        //存放章节信息
        List<CataSimpleInfoDTO> dtos = catalogueClient.batchQueryCatalogue(catalogueIds);
        Map<Long, String>  catalogues= dtos.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId, CataSimpleInfoDTO::getName));
        List<QuestionAdminVO> list = new ArrayList<>();
        for (InteractionQuestion record : records) {
            QuestionAdminVO vo = BeanUtils.copyBean(record, QuestionAdminVO.class);
            vo.setUserName(users.get(record.getUserId()));
            CourseSimpleInfoDTO dto = courseList.get(record.getCourseId());
            if(dto!=null){
                vo.setCourseName(dto.getName());
                //设置多级目录
                String categoryNames = categoryCache.getCategoryNames(dto.getCategoryIds());
                vo.setCategoryName(categoryNames);
            }
            vo.setChapterName(catalogues.get(record.getChapterId()));
            vo.setSectionName(catalogues.get(record.getSectionId()));
            list.add(vo);
        }
        return PageDTO.of(page,list);
    }

    @Override
    public void updateQuestion(QuestionFormDTO dto, Long id) {
        boolean update = this.lambdaUpdate()
                .set(dto.getCourseId() != null, InteractionQuestion::getCourseId, dto.getCourseId())
                .set(dto.getChapterId() != null, InteractionQuestion::getChapterId, dto.getChapterId())
                .set(dto.getSectionId() != null, InteractionQuestion::getSectionId, dto.getSectionId())
                .set(dto.getDescription() != null, InteractionQuestion::getDescription, dto.getDescription())
                .set(dto.getTitle() != null, InteractionQuestion::getTitle, dto.getTitle())
                .set(dto.getAnonymity() != null, InteractionQuestion::getAnonymity, dto.getAnonymity())
                .eq(InteractionQuestion::getId, id)
                .update();
        if(!update){
            throw new DbException("修改问题失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteQuestion(Long id) {
       //- 查询问题是否存在
        InteractionQuestion question = this.getById(id);
        if(ObjectUtils.isEmpty(question)){
            throw new BadRequestException("问题不存在");
        }
        // 判断是否是当前用户提问的
        Long userId = UserContext.getUser();
        if(ObjectUtils.notEqual(userId,question.getUserId())){
            throw new BadRequestException("只能删除自己提出的问题");
        }
        //删除问题
        boolean b = this.removeById(id);
        if(!b){
            throw new DbException("删除问题失败");
        }
        //删除问题下的回答及评论
        List<InteractionReply> list = replyService.lambdaQuery()
                .eq(InteractionReply::getQuestionId, id)
                .list();
        if(CollUtils.isEmpty(list)){
            return;
        }
        Set<Long> set = list.stream().map(InteractionReply::getId).collect(Collectors.toSet());
        boolean b1 = replyService.removeByIds(set);
        if(!b1){
            throw new DbException("删除问题下的回答及评论失败");
        }
    }

    /**
     * 显示或者隐藏问题
     * @param id
     * @param hidden
     */
    @Override
    public void hiddenQuestion(Long id, Boolean hidden) {
        InteractionQuestion question = this.getById(id);
        if(ObjectUtils.isEmpty(question)){
            throw new BadRequestException("问题不存在");
        }
        if(ObjectUtils.equal(question.getHidden(),hidden)){
            throw new BadRequestException("已是想要状态，请勿重复操作");
        }
        boolean update = this.lambdaUpdate()
                .set(InteractionQuestion::getHidden, hidden)
                .eq(InteractionQuestion::getId, id)
                .update();
        if(!update){
            throw new DbException("修改问题失败");
        }
    }

    /**
     * 管理端根据id查询问题详情
     * @param id
     * @return
     */
    @Override
    public QuestionAdminVO getQuestionAdminVO(Long id) {
        //根据id查询问题
        InteractionQuestion question = this.getById(id);
        //判断是否存在
        if(question==null){
            return null;
        }
        //拷贝问题
        QuestionAdminVO vo = BeanUtils.copyBean(question, QuestionAdminVO.class);
        //补充属性
        //用户名
            UserDTO userDTO = userClient.queryUserById(question.getUserId());
            if(userDTO!=null) {
                vo.setUserName(userDTO.getName());
                vo.setUserIcon(userDTO.getIcon());
            }
        //课程名称
        CourseFullInfoDTO courseInfoById = courseClient.getCourseInfoById(question.getCourseId(), true, true);
        vo.setCourseName(courseInfoById.getName());
        //设置三级分类名称
        String categoryNames = categoryCache.getCategoryNames(courseInfoById.getCategoryIds());
        vo.setCategoryName(categoryNames);
        List<Long> cataIds=new ArrayList<>();
        cataIds.add(question.getChapterId());
        cataIds.add(question.getSectionId());
        //设置章名称
        List<CataSimpleInfoDTO> cataSimpleInfoDTOS = catalogueClient.batchQueryCatalogue(cataIds);
        Map<Long, String> collect = cataSimpleInfoDTOS.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId, CataSimpleInfoDTO::getName));
        vo.setChapterName(collect.get(question.getChapterId()));
        //设置节名称
        vo.setChapterName(collect.get(question.getSectionId()));
        List<Long> teacherIds = courseInfoById.getTeacherIds();
        List<UserDTO> user = userClient.queryUserByIds(teacherIds);
        String name="";
        for (UserDTO dto : user) {
            name+=dto.getName()+" ";
        }
        vo.setTeacherName(name);
        return vo;
    }
}